import { Vec3 } from '@/core/types';
import { Entity } from '@/entities/Entity';
import { getEntityPersona } from './EntityPersonas';

/**
 * 智能对话目标选择器
 * 负责自动选择最合适的对话目标，处理多生物场景
 */
export class TargetSelector {
    private currentTarget: Entity | null = null;
    private maxDetectionRange: number = 10; // 最大检测范围
    private targetSwitchCooldown: number = 1000; // 目标切换冷却时间（毫秒）
    private lastTargetSwitchTime: number = 0;
    private conversationInProgress: boolean = false;

    constructor(maxDetectionRange: number = 10) {
        this.maxDetectionRange = maxDetectionRange;
    }

    /**
     * 自动选择最佳对话目标
     * 需求 5.1: 单个生物时的自动选择逻辑
     * 需求 5.2: 多个生物时选择最近生物的算法
     */
    public selectBestTarget(playerPosition: Vec3, entities: Entity[]): Entity | null {
        // 过滤出有效的对话目标
        const validTargets = entities.filter(entity => this.isValidTarget(entity, playerPosition));

        // 需求 5.5: 无生物时返回null（调用方会显示提示信息）
        if (validTargets.length === 0) {
            // 如果当前有目标但现在没有有效目标，清除当前目标
            if (this.currentTarget) {
                this.currentTarget = null;
                this.conversationInProgress = false;
            }
            return null;
        }

        // 需求 5.1: 单个生物时自动选择
        if (validTargets.length === 1) {
            const target = validTargets[0];
            this.setCurrentTarget(target);
            return target;
        }

        // 需求 5.2: 多个生物时选择最近的生物
        // 需求 5.3: 对话过程中保持目标的逻辑
        if (this.conversationInProgress && this.currentTarget && this.isValidTarget(this.currentTarget, playerPosition)) {
            // 如果正在对话且当前目标仍然有效，保持当前目标
            return this.currentTarget;
        }

        // 选择最近的生物
        const closestTarget = this.findClosestTarget(playerPosition, validTargets);
        
        // 检查是否需要切换目标（避免频繁切换）
        if (this.shouldSwitchTarget(closestTarget)) {
            this.setCurrentTarget(closestTarget);
            return closestTarget;
        }

        // 如果不需要切换，返回当前目标（如果有效）或最近的目标
        return this.currentTarget && this.isValidTarget(this.currentTarget, playerPosition) 
            ? this.currentTarget 
            : closestTarget;
    }

    /**
     * 计算目标优先级
     * 考虑距离、生物类型、对话历史等因素
     */
    public calculateTargetPriority(entity: Entity, playerPosition: Vec3): number {
        let priority = 0;

        // 距离因子（距离越近优先级越高）
        const distance = this.calculateDistance(playerPosition, entity.getPosition());
        const maxDistance = this.maxDetectionRange;
        const distanceFactor = Math.max(0, (maxDistance - distance) / maxDistance);
        priority += distanceFactor * 100;

        // 生物类型因子（某些生物类型可能有更高优先级）
        const entityType = entity.getType();
        const typeBonus = this.getEntityTypeBonus(entityType);
        priority += typeBonus;

        // 如果是当前目标，给予额外优先级（保持对话连续性）
        if (this.currentTarget && entity.getId() === this.currentTarget.getId()) {
            priority += 50;
        }

        // 健康状态因子（健康的生物优先级更高）
        if (entity.isAlive()) {
            priority += 20;
        }

        return priority;
    }

    /**
     * 检查目标有效性
     */
    public isValidTarget(entity: Entity, playerPosition?: Vec3): boolean {
        if (!entity || !entity.isAlive()) {
            return false;
        }

        // 检查是否有对应的个性配置
        const persona = getEntityPersona(entity.getType());
        if (!persona) {
            return false;
        }

        // 如果提供了玩家位置，检查距离
        if (playerPosition) {
            const distance = this.calculateDistance(playerPosition, entity.getPosition());
            if (distance > this.maxDetectionRange) {
                return false;
            }
        }

        return true;
    }

    /**
     * 处理目标切换
     * 需求 5.4: 目标离开范围时的自动切换功能
     */
    public switchTarget(newTarget: Entity | null): void {
        const previousTarget = this.currentTarget;
        this.setCurrentTarget(newTarget);
        
        // 如果切换了目标，重置对话状态
        if (previousTarget && newTarget && previousTarget.getId() !== newTarget.getId()) {
            this.conversationInProgress = false;
        }
    }

    /**
     * 获取当前目标
     */
    public getCurrentTarget(): Entity | null {
        return this.currentTarget;
    }

    /**
     * 设置对话进行状态
     */
    public setConversationInProgress(inProgress: boolean): void {
        this.conversationInProgress = inProgress;
    }

    /**
     * 检查当前目标是否仍在有效范围内
     * 需求 5.4: 目标离开范围时的自动切换功能
     */
    public checkCurrentTargetValidity(playerPosition: Vec3): boolean {
        if (!this.currentTarget) {
            return false;
        }

        if (!this.isValidTarget(this.currentTarget, playerPosition)) {
            // 目标已无效，清除当前目标
            this.currentTarget = null;
            this.conversationInProgress = false;
            return false;
        }

        return true;
    }

    /**
     * 更新检测范围
     */
    public setDetectionRange(range: number): void {
        this.maxDetectionRange = Math.max(1, range);
    }

    /**
     * 获取检测范围
     */
    public getDetectionRange(): number {
        return this.maxDetectionRange;
    }

    /**
     * 查找最近的目标
     */
    private findClosestTarget(playerPosition: Vec3, entities: Entity[]): Entity {
        let closestEntity = entities[0];
        let closestDistance = this.calculateDistance(playerPosition, closestEntity.getPosition());

        for (let i = 1; i < entities.length; i++) {
            const distance = this.calculateDistance(playerPosition, entities[i].getPosition());
            if (distance < closestDistance) {
                closestDistance = distance;
                closestEntity = entities[i];
            }
        }

        return closestEntity;
    }

    /**
     * 计算两点之间的距离
     */
    private calculateDistance(pos1: Vec3, pos2: Vec3): number {
        const dx = pos1.x - pos2.x;
        const dy = pos1.y - pos2.y;
        const dz = pos1.z - pos2.z;
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    }

    /**
     * 设置当前目标
     */
    private setCurrentTarget(target: Entity | null): void {
        this.currentTarget = target;
        this.lastTargetSwitchTime = Date.now();
    }

    /**
     * 判断是否应该切换目标
     */
    private shouldSwitchTarget(newTarget: Entity | null): boolean {
        // 如果没有新目标，不切换
        if (!newTarget) {
            return false;
        }

        // 如果没有当前目标，直接切换
        if (!this.currentTarget) {
            return true;
        }

        // 如果是同一个目标，不切换
        if (newTarget.getId() === this.currentTarget.getId()) {
            return false;
        }

        // 检查冷却时间
        const currentTime = Date.now();
        if (currentTime - this.lastTargetSwitchTime < this.targetSwitchCooldown) {
            return false;
        }

        // 如果正在对话，需要更严格的条件才切换
        if (this.conversationInProgress) {
            // 只有当新目标明显更近时才切换（至少近2格）
            const currentDistance = this.calculateDistance(
                this.currentTarget.getPosition(), 
                newTarget.getPosition()
            );
            return currentDistance > 2;
        }

        return true;
    }

    /**
     * 获取生物类型的优先级加成
     */
    private getEntityTypeBonus(entityType: string): number {
        // 根据生物类型给予不同的优先级加成
        const bonusMap: Record<string, number> = {
            'cow': 10,      // 牛比较友善
            'pig': 8,       // 猪比较可爱
            'sheep': 12,    // 羊比较温顺
            'zombie': 5,    // 僵尸优先级较低
            'skeleton': 3   // 骷髅优先级最低
        };

        return bonusMap[entityType] || 0;
    }

    /**
     * 获取在范围内的所有有效目标
     */
    public getValidTargetsInRange(playerPosition: Vec3, entities: Entity[]): Entity[] {
        return entities.filter(entity => this.isValidTarget(entity, playerPosition));
    }

    /**
     * 重置选择器状态
     */
    public reset(): void {
        this.currentTarget = null;
        this.conversationInProgress = false;
        this.lastTargetSwitchTime = 0;
    }

    /**
     * 获取选择器状态信息
     */
    public getStatus(): {
        currentTarget: Entity | null;
        conversationInProgress: boolean;
        detectionRange: number;
        lastSwitchTime: number;
    } {
        return {
            currentTarget: this.currentTarget,
            conversationInProgress: this.conversationInProgress,
            detectionRange: this.maxDetectionRange,
            lastSwitchTime: this.lastTargetSwitchTime
        };
    }
}